<template>
  <div>
    <div class="card-title card-title-background">户基本信息</div>
    <a-form
      ref="formRef"
      layout="inline"
      :model="form"
      :rules="rules"
      :label-col="{ md: { span: 10 }, sm: { span: 24 } }"
      :wrapper-col="{ md: { span: 18 }, sm: { span: 24 } }"
    >
      <a-form-item label="户编号:" name="householdNo">
        <a-input
          v-model:value="form.householdNo"
          placeholder="请输入户编号"
          :readonly="!editable"
          allow-clear
        />
      </a-form-item>
      <a-form-item label="户主姓名:" name="householdOwnerName">
        <a-input v-model:value="form.householdOwnerName" placeholder="请输入户主姓名" readonly />
      </a-form-item>
      <a-form-item label="户所在地:" name="householdAddress">
        <a-input
          v-model:value="form.householdAddress"
          placeholder="请输入户所在地"
          :readonly="!editable"
          allow-clear
        />
      </a-form-item>
    </a-form>
    <div class="card-title card-title-background">户实物指标信息</div>
    <a-tabs tab-position="left">
      <a-tab-pane key="1">
        <template #tab>
          <span>家庭成员信息({{ form.members ? form.members.length : 0 }})</span>
        </template>
        <BasicTable
          :canResize="false"
          :pagination="false"
          ref="memberTableRef"
          :columns="memberColumns"
          :dataSource="form.members"
          rowKey="memberId"
        >
          <!-- table上边工具栏 -->
          <template #toolbar>
            <div class="table-toolbar" v-show="editable">
              <a-space>
                <a-button type="primary" @click="addMemberRow()">
                  <template #icon>
                    <plus-outlined />
                  </template>
                  <span>新增</span>
                </a-button>
              </a-space>
            </div>
          </template>

          <template #bodyCell="{ text, column, record }">
            <!-- table操作栏按钮 -->
            <template v-if="column.key === 'action'">
              <a-space v-if="editable">
                <a v-if="record.editable" @click="saveMember(record)">保存</a>
                <a v-else @click="editMember(record)">编辑</a>
                <a-popconfirm title="确定要删除此家庭成员吗？" @confirm="removeMember(record)">
                  <a class="guns-text-danger">删除</a>
                </a-popconfirm>
              </a-space>
            </template>
            <template v-else-if="column.dataIndex == 'memberType'">
              <a-select
                v-model:value="record.memberType"
                style="width: 120px"
                @change="changeMemberType"
                :disabled="!editable"
              >
                <a-select-option
                  v-for="memberType in memberTypeOptions"
                  :key="memberType.value"
                  :value="memberType.value"
                  :disabled="memberType.disabled"
                >
                  {{ memberType.label }}
                </a-select-option>
              </a-select>
            </template>
            <template v-else-if="column.dataIndex">
              <div class="editable-cell">
                <div v-if="record.editable" class="editable-cell-input-wrapper">
                  <a-input
                    v-if="column.dataIndex == 'name'"
                    v-model:value="record[column.dataIndex]"
                    @change="changeMemberName(record)"
                    @blur="validateMember(record, column.dataIndex)"
                  />
                  <a-input
                    v-else
                    v-model:value="record[column.dataIndex]"
                    @blur="validateMember(record, column.dataIndex)"
                    :readonly="column.dataIndex == 'birthday'"
                  />
                </div>
                <div v-else class="editable-cell-text-wrapper">
                  <span>{{ text || ' ' }}</span>
                </div>
              </div>
            </template>
          </template>
        </BasicTable>
      </a-tab-pane>
      <a-tab-pane key="2">
        <template #tab>
          <span>房屋信息({{ form.housingInfos ? form.housingInfos.length : 0 }})</span>
        </template>
        <BasicTable
          :canResize="false"
          :pagination="false"
          ref="housingTableRef"
          :columns="housingColumns"
          :dataSource="form.housingInfos"
          rowKey="housingId"
        >
          <!-- table上边工具栏 -->
          <template #toolbar>
            <div class="table-toolbar" v-show="editable">
              <a-space>
                <a-button type="primary" @click="addHousingRow()">
                  <template #icon>
                    <plus-outlined />
                  </template>
                  <span>新增</span>
                </a-button>
              </a-space>
            </div>
          </template>

          <template #bodyCell="{ text, column, record }">
            <!-- table操作栏按钮 -->
            <template v-if="column.key === 'action'">
              <a-space v-if="editable">
                <a v-if="record.editable" @click="saveHousing(record)">保存</a>
                <a v-else @click="editHousing(record)">编辑</a>
                <a-popconfirm title="确定要删除此房屋信息吗？" @confirm="removeHousing(record)">
                  <a class="guns-text-danger">删除</a>
                </a-popconfirm>
              </a-space>
            </template>
            <template v-else-if="column.dataIndex == 'housingOwnerId'">
              <a-select
                v-model:value="record.housingOwnerId"
                style="width: 120px"
                :disabled="!editable"
              >
                <a-select-option
                  v-for="member in form.members"
                  :key="member.memberId"
                  :value="member.memberId"
                  :disabled="!member.name"
                >
                  {{ member.name || '&lt;未填写&gt;' }}
                </a-select-option>
              </a-select>
            </template>
            <template v-else-if="column.dataIndex">
              <div class="editable-cell">
                <div v-if="record.editable" class="editable-cell-input-wrapper">
                  <a-input
                    v-model:value="record[column.dataIndex]"
                    @blur="validateHousing(record, column.dataIndex)"
                  />
                </div>
                <div v-else class="editable-cell-text-wrapper">
                  <span>{{ text || ' ' }}</span>
                </div>
              </div>
            </template>
          </template>

          <template #footer>
            <a-row>
              <a-col :span="editable ? 15 : 19" style="padding-left: 5px">合计</a-col>
              <a-col :span="5" class="housing-area-total">{{ housingAreaTotal }}</a-col>
            </a-row>
          </template>
        </BasicTable>
      </a-tab-pane>
    </a-tabs>
  </div>
</template>

<script lang="ts" setup>
  import {computed, reactive, ref, unref, watch} from 'vue';
  import { BasicTable } from '/@/components/Table';
  import { cloneDeep } from 'lodash-es';
  import { message } from 'ant-design-vue';

  const props = defineProps<{
    // 表单数据
    form: Object;
    // 是否可编辑
    editable: Boolean;
  }>();

  // 验证规则
  const rules = reactive({
    householdNo: [{ required: true, message: '请输入户编号', type: 'string', trigger: 'blur' }],
    householdOwnerName: [
      { required: true, message: '请输入户主姓名', type: 'string', trigger: 'blur' },
    ],
    householdAddress: [
      { required: true, message: '请输入户所在地', type: 'string', trigger: 'blur' },
    ],
  });

  // 家庭成员验证规则
  const memberRules = reactive({
    name: [{ required: true, message: '请输入姓名' }],
    memberType: [{ required: true, message: '请选择与户主关系' }],
    idCard: [
      { required: true, message: '请输入身份证号' },
      {
        regex: true,
        pattern:
          /^[1-9]\d{5}(18|19|20|21|22)?\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|[Xx])$/,
        message: '请输入正确的身份证号',
      },
    ],
    birthday: [{ required: true, message: '请输入出生日期' }],
  });

  // 家庭成员表格列配置
  const memberColumns = ref<Object[]>([
    {
      title: '姓名',
      dataIndex: 'name',
      width: 150,
    },
    {
      title: '与户主关系',
      dataIndex: 'memberType',
      width: 150,
    },
    {
      title: '身份证号',
      dataIndex: 'idCard',
      width: 220,
    },
    {
      title: '出生日期',
      dataIndex: 'birthday',
      width: 120,
    },
  ]);

  if (props.editable) {
    memberColumns.value.push({
      title: '操作',
      key: 'action',
      width: 150,
      align: 'center',
    });
  }

  watch(
    () => props.editable,
    (val) => {
      if (val) {
        memberColumns.value.push({
          title: '操作',
          key: 'action',
          width: 150,
          align: 'center',
        });
      } else {
        memberColumns.value.pop();
      }
    },
  );

  const memberTypeOptions = ref([
    {
      value: '1',
      label: '户主',
      disabled: props.form.members && props.form.members.length > 0,
    },
    {
      value: '2',
      label: '配偶',
      disabled: false,
    },
    {
      value: '3',
      label: '子女',
      disabled: false,
    },
    {
      value: '4',
      label: '孙子女',
      disabled: false,
    },
    {
      value: '5',
      label: '父母',
      disabled: false,
    },
    {
      value: '6',
      label: '祖父母',
      disabled: false,
    },
    {
      value: '7',
      label: '外祖父母',
      disabled: false,
    },
    {
      value: '8',
      label: '兄弟姊妹',
      disabled: false,
    },
  ]);

  /**
   * 验证家庭成员
   *
   * @author: lichenhui
   * @date: 2024-03-22 10:07
   */
  const validateMember = (row, key) => {
    let validKeys = ref<string[]>([]);
    if (key) {
      validKeys.value.push(key);
    } else {
      validKeys.value.push('name', 'memberType', 'idCard', 'birthday');
    }
    for (const item of validKeys.value) {
      for (const rule of memberRules[item]) {
        if (rule.required && !row[item]) {
          message.warn(rule.message);
          return false;
        }
        if (rule.regex && !rule.pattern.test(row[item])) {
          message.warn(rule.message);
          return false;
        }
      }
    }
    if (key === 'idCard') {
      row.birthday =
        row.idCard.substring(6, 10) +
        '-' +
        row.idCard.substring(10, 12) +
        '-' +
        row.idCard.substring(12, 14);
    }
    return true;
  };

  let memberIdCounter = ref(0);

  /**
   * 添加家庭成员
   *
   * @author: lichenhui
   * @date: 2024-03-21 15:07
   */
  const addMemberRow = () => {
    props.form.members = props.form.members || ref([]);
    props.form.members.push({
      memberId: ++memberIdCounter.value,
      name: '',
      memberType: '',
      idCard: '',
      birthday: '',
      editable: true,
    });
  };

  /**
   * 保存家庭成员
   *
   * @author: lichenhui
   * @date: 2024-03-21 15:07
   */
  const saveMember = (row) => {
    row.editable = !validateMember(row);
  };

  /**
   * 编辑家庭成员
   *
   * @author: lichenhui
   * @date: 2024-03-21 15:07
   */
  const editMember = (row) => {
    row.editable = true;
  };

  /**
   * 删除家庭成员
   *
   * @author: lichenhui
   * @date: 2024-03-21 15:07
   */
  const removeMember = (row) => {
    if (
      props.form.housingInfos &&
      props.form.housingInfos.filter((item) => row.memberId === item.housingOwnerId).length > 0
    ) {
      message.warn('请先删除指标信息');
      return false;
    }
    if (row.memberType === '1') {
      props.form.householdOwnerName = '';
    }
    props.form.members = cloneDeep(
      props.form.members.filter((item) => row.memberId !== item.memberId),
    );
  };

  /**
   * 监听家庭成员姓名变更
   *
   * @author: lichenhui
   * @date: 2024-03-22 09:07
   */
  const changeMemberName = (row) => {
    if (row.memberType === '1') {
      props.form.householdOwnerName = row.name;
    }
  };

  /**
   * 监听家庭成员类型变更
   *
   * @author: lichenhui
   * @date: 2024-03-22 09:07
   */
  const changeMemberType = (value) => {
    if (value === '1') {
      memberTypeOptions.value[0].disabled = true;
      props.form.householdOwnerName = props.form.members.filter(
        (item) => '1' === item.memberType,
      )[0].name;
    }
    if (props.form.members.filter((item) => '1' === item.memberType).length === 0) {
      memberTypeOptions.value[0].disabled = false;
      props.form.householdOwnerName = '';
    }
  };

  // 房屋信息验证规则
  const housingRules = reactive({
    housingOwnerId: [{ required: true, message: '请选择权属人' }],
    housingAddress: [{ required: true, message: '请输入所在行政区别' }],
    housingArea: [
      { required: true, message: '请输入房屋面积' },
      { regex: true, pattern: /^\d+(\.\d+)?$/, message: '请输入正确的房屋面积' },
    ],
  });

  // 房屋信息表格列配置
  const housingColumns = ref<Object[]>([
    {
      title: '权属人',
      dataIndex: 'housingOwnerId',
      width: 150,
    },
    {
      title: '所在行政区别',
      dataIndex: 'housingAddress',
      width: 300,
    },
    {
      title: '房屋面积（㎡）',
      dataIndex: 'housingArea',
      width: 150,
    },
  ]);

  if (props.editable) {
    housingColumns.value.push({
      title: '操作',
      key: 'action',
      width: 150,
      align: 'center',
    });
  }

  watch(
    () => props.editable,
    (val) => {
      if (val) {
        housingColumns.value.push({
          title: '操作',
          key: 'action',
          width: 150,
          align: 'center',
        });
      } else {
        housingColumns.value.pop();
      }
    },
  );

  // 房屋总面积
  const housingAreaTotal = computed(() => {
    if (!props.form.housingInfos) {
      return 0;
    }
    let total = 0;
    for (const item of props.form.housingInfos) {
      total += !item.housingArea || isNaN(item.housingArea) ? 0 : parseFloat(item.housingArea);
    }
    return total;
  });

  /**
   * 验证房屋信息
   *
   * @author: lichenhui
   * @date: 2024-03-22 10:07
   */
  const validateHousing = (row, key) => {
    let validKeys = ref<string[]>([]);
    if (key) {
      validKeys.value.push(key);
    } else {
      validKeys.value.push('housingOwnerId', 'housingAddress', 'housingArea');
    }
    for (const item of validKeys.value) {
      for (const rule of housingRules[item]) {
        if (rule.required && !row[item]) {
          message.warn(rule.message);
          return false;
        }
        if (rule.regex && !rule.pattern.test(row[item])) {
          message.warn(rule.message);
          return false;
        }
      }
    }
    return true;
  };

  let housingIdCounter = ref(0);

  /**
   * 添加房屋信息
   *
   * @author: lichenhui
   * @date: 2024-03-22 09:07
   */
  const addHousingRow = () => {
    props.form.housingInfos = props.form.housingInfos || ref([]);
    props.form.housingInfos.push({
      housingId: ++housingIdCounter.value,
      housingOwnerId: '',
      housingAddress: '',
      housingArea: '',
      editable: true,
    });
  };

  /**
   * 保存房屋信息
   *
   * @author: lichenhui
   * @date: 2024-03-22 09:07
   */
  const saveHousing = (row) => {
    row.editable = !validateHousing(row);
  };

  /**
   * 编辑房屋信息
   *
   * @author: lichenhui
   * @date: 2024-03-22 09:07
   */
  const editHousing = (row) => {
    row.editable = true;
  };

  /**
   * 删除房屋信息
   *
   * @author: lichenhui
   * @date: 2024-03-22 09:07
   */
  const removeHousing = (row) => {
    props.form.housingInfos = cloneDeep(
      props.form.housingInfos.filter((item) => row.housingId !== item.housingId),
    );
  };
</script>

<style lang="less" scoped>
  .card-title {
    border-left: 5px solid;
    border-color: var(--primary-color);
    padding-left: 10px;
  }

  .card-title-background {
    background-color: #f5f5f5;
    height: 2em;
    line-height: 2em;
    margin-bottom: 2em;
  }

  .ant-form-inline .ant-form-item {
    margin-bottom: 15px;
  }

  .housing-area-total {
    text-align: center;
    margin-left: -5px;
  }
</style>
